package com.example.houselease.service.impl;

import com.example.houselease.mapper.RoleMapper;
import com.example.houselease.pojo.dto.admin.RoleAddNewDTO;
import com.example.houselease.pojo.dto.admin.PermissionDTO;
import com.example.houselease.pojo.dto.admin.RolePermissionDTO;
import com.example.houselease.pojo.dto.admin.RoleUpdateDTO;
import com.example.houselease.pojo.entity.Role;
import com.example.houselease.pojo.vo.RoleDetailVO;
import com.example.houselease.pojo.vo.RoleListVO;
import com.example.houselease.pojo.vo.RolePerDetailVO;
import com.example.houselease.service.IRoleService;
import com.example.houselease.util.ErrorUtils;
import com.example.houselease.web.ServiceCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 角色 service 实现类
 * @author sf
 * @version 0.0.1
 * */
@Service
@Slf4j
@Transactional
public class IRoleServiceImpl implements IRoleService {

    @Autowired
    private RoleMapper roleMapper;

    @Override
    public List<RoleListVO> list() {
        return roleMapper.select();
    }

    @Override
    public void add(RoleAddNewDTO roleAddNewDTO) {
        log.debug("开始处理【添加角色】业务，参数：{}",roleAddNewDTO);
        Role role = new Role();
        BeanUtils.copyProperties(roleAddNewDTO,role);
        int insert = roleMapper.insert(role);
        ErrorUtils.isFail(insert, ServiceCode.ERR_INSERT);
    }

    @Override
    public void nameIsAlready(String name) {
        log.debug("开始处理【检测角色名称是否已经存在】业务，参数：{}",name);
        int i = roleMapper.countByName(name);
        ErrorUtils.isExists(i,"该名称已经存在，请换一个");
    }

    @Override
    public void regPer(Long roleId, List<Long> perIds) {
        log.debug("开始处理【注册角色权限】业务，参数1：{}，参数2：{}",roleId,perIds);
        RoleDetailVO roleDetailVO = roleMapper.selectById(roleId);
        ErrorUtils.isNull(roleDetailVO,"注册权限失败，该角色数据不存在");
        //通过角色id，查询所拥有的权限信息
        List<RolePerDetailVO> oldRolePers = roleMapper.selectPerById(roleId);
        List<Long> oldPerIds = new ArrayList<>();
        oldRolePers.forEach(rp -> oldPerIds.add(rp.getId()));
        Collections.sort(oldPerIds);
        Collections.sort(perIds);
        int count = 1;
        if (!perIds.equals(oldPerIds)){
            //获取数据库中不存在的角色权限数据
            List<Long> newRolePerIds = perIds.stream().filter(i -> !oldPerIds.contains(i)).collect(Collectors.toList());
            if (newRolePerIds.size()>0){
                log.debug("开始插入新的，管理员角色关联数据id，roleId：{}，perId列表：{}",roleId,newRolePerIds);
                count = roleMapper.insertRolePer(roleId, newRolePerIds);
                ErrorUtils.isFail(count,ServiceCode.ERR_UPDATE);
            }
            //获取用户传递的，跟数据库中存在的，重合的数据。将其改为启用状态
            List<Long> alreadyRolePerIds = perIds.stream().filter(i -> oldPerIds.contains(i)).collect(Collectors.toList());
            if (alreadyRolePerIds.size()>0){
                log.debug("开始启用数据库已有的，管理员角色关联数据id，roleId：{}，perId列表：{}",roleId,alreadyRolePerIds);
                count = roleMapper.updateRolePerEnable(roleId, alreadyRolePerIds);
            }
            //获取用户传递的，跟数据库中存在的，不重合的数据。将其改为禁用状态
            List<Long> disableRolePerIds = oldPerIds.stream().filter(i -> !perIds.contains(i)).collect(Collectors.toList());
            if (disableRolePerIds.size()>0){
                log.debug("开始禁用数据库已有的，管理员角色关联数据id，roleId：{}，perId列表：{}",roleId,disableRolePerIds);
                count = roleMapper.updateRolePerDisable(roleId, disableRolePerIds);
            }
        }else {
            List<Long> enableRolePerIds = new ArrayList<>();
            oldRolePers.forEach(rp -> {if (rp.getEnable()==0)
                enableRolePerIds.add(rp.getId());});
            count = roleMapper.updateRolePerEnable(roleId,enableRolePerIds);
        }
        ErrorUtils.isFail(count,ServiceCode.ERR_UPDATE);
    }

    @Override
    public List<Long> getRolePerById(Long id) {
        log.debug("开始处理【获取角色的权限id详情】业务，参数：{}",id);
        RoleDetailVO roleDetailVO = roleMapper.selectById(id);
        ErrorUtils.isNull(roleDetailVO,"注册权限失败，该角色数据不存在");
        //查询启用的角色权限信息
        List<RolePerDetailVO> rolePers = roleMapper.selectPerEnableById(id,1);
        List<Long> rolePerIds = new ArrayList<>();
        rolePers.forEach(rp -> rolePerIds.add(rp.getId()));
        return rolePerIds;
    }

    @Override
    public void deleteById(Long id) {
        log.debug("开始处理【删除角色】业务，参数：{}",id);
        RoleDetailVO roleDetailVO = roleMapper.selectById(id);
        ErrorUtils.isNull(roleDetailVO,"删除失败，该数据不存在");
        int i = roleMapper.deleteById(id);
        ErrorUtils.isFail(i,ServiceCode.ERR_DELETE);
        int i2 = roleMapper.deleteAdminRoleByRoleId(id);
        if (i2<0){
            ErrorUtils.isFail(i2,ServiceCode.ERR_DELETE);
        }
    }

    @Override
    public RoleDetailVO getRoleDetail(Long id) {
        log.debug("开始处理【角色详情】业务，参数：{}",id);
        RoleDetailVO roleDetailVO = roleMapper.selectById(id);
        ErrorUtils.isNull(roleDetailVO,"修改失败，该数据不存在");
        return roleDetailVO;
    }

    @Override
    public void enable(Long id) {
        log.debug("开始处理【启用角色】业务，参数：{}",id);
        RoleDetailVO roleDetailVO = roleMapper.selectById(id);
        ErrorUtils.isNull(roleDetailVO,"启用失败，该数据不存在");
        int i = roleMapper.updateRoleEnable(id);
        ErrorUtils.isFail(i,ServiceCode.ERR_UPDATE);
    }

    @Override
    public void disable(Long id) {
        log.debug("开始处理【禁用角色】业务，参数：{}",id);
        RoleDetailVO roleDetailVO = roleMapper.selectById(id);
        ErrorUtils.isNull(roleDetailVO,"禁用失败，该数据不存在");
        int i = roleMapper.updateRoleDisable(id);
        ErrorUtils.isFail(i,ServiceCode.ERR_UPDATE);
    }

    @Override
    public void update(Long id, RoleUpdateDTO roleUpdateDTO) {
        log.debug("开始处理【修改角色】业务，参数1：{}，参数2：{}",id,roleUpdateDTO);
        RoleDetailVO roleDetailVO = roleMapper.selectById(id);
        ErrorUtils.isNull(roleDetailVO,"修改失败，该数据不存在");
        Role role = new Role();
        BeanUtils.copyProperties(roleUpdateDTO,role);
        role.setId(id);
        roleMapper.update(role);
    }
}
